/**
 * 登录控制器模块
 */
module controller.LoginController;

import vibe.http.server : HTTPServerRequest, HTTPServerResponse;
import vibe.data.json : Json;
import model.User;
import repository.UserRepo;
import utils.RespData : RespData;
import utils.ConstValue : Const;
import utils.MyJwt;
import utils.DataCache;

import std.stdio;

UserRepo _uRepo;

static this ()
{
    _uRepo = new UserRepo();
}

static ~this ()
{
    destroy(_uRepo);
}

/** 
 * 用户登录
 */
void uearLogin (HTTPServerRequest req, HTTPServerResponse resp)
{
    import std.digest : toHexString;
    import std.digest.md : md5Of;
    import std.conv : to;
    import std.datetime.systime : Clock;
    import core.time : seconds;

    import vibe.data.json : Json;
    import cachetools : TTL;

    string ip = req.clientAddress.toAddressString();

    // 缓存中有ip记录
    auto data = cacheData.get(ip);
    if (!data.isNull)
    {
        uint count = to!uint(data.get);
        // 超过次数限制直接拒绝
        if ((count + 1) >= 6)
        {
            resp.writeJsonBody(RespData.newData(403, "您的操作过于频繁，请稍后再试。"), 403);
            return;
        }
        // 没超过次数限制
        // 设置缓存，记录IP
        cacheData.put(ip, to!string(count + 1), TTL(180.seconds));
    }
    else
    {
        // 缓存中没有ip记录
        // 设置缓存，记录IP
        cacheData.put(ip, to!string(1), TTL(180.seconds));
    }

    // 接收前端数据
    Json json = req.json;
    if (json.length == 0)
    {
        resp.writeJsonBody(RespData.newData(400, "错误的请求"), 400);
        return;
    }
    string username = json["username"].to!string();
    string plainPwd = json["password"].to!string();
    if (username == "" || plainPwd == "")
    {
        resp.writeJsonBody(RespData.newData(400, "错误的请求"), 400);
        return;
    }
    // 明文密码md5加密
    string password = to!string(toHexString(md5Of(Const.saltStr ~ plainPwd)));
    // 验证是否查询到记录
    User user = _uRepo.getOneUser(username, password);
    if (user is null) // 没有记录
    {
        resp.writeJsonBody(RespData.newData(400, "用户名或密码错误"), 400);
        return;
    }

    // 生成jwt token
    long exp = Clock.currTime.toUnixTime() + 7200;
    Json userData = Json([
        "id" : Json(user.id),
        "username" : Json(user.username),
        "exp" : Json(exp),
    ]);
    string token = createToken(userData);
    Json resData = Json([
        "id" : Json(user.id),
        "username" : Json(user.username),
        "role" : Json(user.role),
        "token" : Json(token),
    ]);
    resp.writeJsonBody(RespData.newData(200, "ok", resData));
}

/** 
 * 用户退出登录
 */
void userLogout (HTTPServerRequest req, HTTPServerResponse resp)
{
    resp.writeJsonBody(RespData.newData(200, "ok"));
}
